package cn.itcast.nems.journal.util;

import cn.itcast.nems.common.account.AccountInfo;
import cn.itcast.nems.employee.dao.entity.Employee;
import cn.itcast.nems.journal.dto.JournalTransferInfoBDtoLine;
import cn.itcast.nems.journal.dto.JournalTransferInfoBDtoLineDiscount;
import cn.itcast.nems.studentrecord.constant.DiscountScopeTypeEnum;
import com.itcast.msas.sdk.acm.domain.AccountDto;
import jline.internal.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 转班用到的一些工具代码
 */
public class TransferUtils {

    /**
     * 金额格式化格式 （千分符小数点后两位）
     */
    private static final DecimalFormat df = new DecimalFormat("#,###.00");

    /**
     * 格式化账户信息
     *
     * @param account 账户信息
     * @return 格式化后的账户信息
     */
    public static String formatAccount(AccountInfo account) {
        return account.getName() + "（" + account.getEmail() + "）";
    }

    /**
     * 格式化账户信息
     *
     * @param account 账户信息
     * @return 格式化后的账户信息
     */
    public static String formatAccount(AccountDto account) {
        return account.getName() + "（" + account.getUsername() + "）";
    }

    public static String formatAccount(Employee account, String email) {
        if (account == null) {
            return StringUtils.hasText(email) ? email : "";
        }
        return account.getName() + "（" + account.getEmail() + "）";
    }

    public static String accountName(Employee account, String email) {
        if (account == null) {
            return StringUtils.hasText(email) ? email : "";
        }
        return account.getName();
    }

    /**
     * 将分转化为千分符带两位小数的字符串
     * <p>
     * 例如
     * 1000 -> 10.00
     * 1000001 -> 10,000.01
     *
     * @param price 分
     * @return 千分符带两位小数的字符串
     */
    public static String formatPrice(Integer price) {
        if (price == null) return null;
        var result = df.format(new BigDecimal(price).divide(BigDecimal.valueOf(100)));
        if (result.charAt(0) == '.') {
            return "0" + result;
        }
        return result;
    }

    /**
     * 将千分符带两位小数的字符串转化为分
     * <p>
     * 例如
     * 10.00 -> 1000
     * 10,000.01 -> 1000001
     *
     * @param priceFormatted 千分符带两位小数的字符串
     * @return 分
     */
    public static Integer parsePrice(String priceFormatted) {
        if (priceFormatted == null) return null;
        try {
            // 兼容 1,000.01 和 1000.01 两种格式
            final var n = (new DecimalFormat("#,###.00").parse(priceFormatted));
            final var b = new BigDecimal(n.toString()).multiply(new BigDecimal(100));
            return b.intValue();
        } catch (ParseException e) {
            Assert.isTrue(false, "价格格式错误, 格式应为: #,###.00 即小数点两位带千分符");
            return null;
        }
    }

    /**
     * <p>
     * 合并凭单行中的普通优惠和个人优惠
     * </p>
     *
     * @param lineDTO 页面参数
     * @author zhouwei
     * @since 2023/12/8 3:20 PM
     **/
    public static List<JournalTransferInfoBDtoLineDiscount> getLineDiscountList(JournalTransferInfoBDtoLine lineDTO) {
        List<JournalTransferInfoBDtoLineDiscount> discountList = new ArrayList<>();
        discountList.addAll(Objects.requireNonNullElse(lineDTO.getDiscountList(), new ArrayList<JournalTransferInfoBDtoLineDiscount>())
                .stream().peek(item -> item.setDiscountScopeType(DiscountScopeTypeEnum.NORMAL.name())).toList());
        discountList.addAll(Objects.requireNonNullElse(lineDTO.getDiscountCouponList(), new ArrayList<JournalTransferInfoBDtoLineDiscount>())
                .stream().peek(item -> item.setDiscountScopeType(DiscountScopeTypeEnum.PERSONAL.name())).toList());
        return discountList;
    }

    /**
     * 将 LocalDate 转换为 LocalDateTime 如果是null则返回null
     * <p>
     *
     * @param date LocalDate
     * @return LocalDateTime
     */
    @Nullable
    public static LocalDateTime localToTime(@Nullable LocalDate date) {
        return date == null ? null : date.atStartOfDay();
    }

}
